个人博客

学习加油站


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

浅谈 var、let 和 const (一)

发表于 2019-08-13 更新于 2019-08-16

浅谈 var、let 和 const (一)

前言

ES6新增了 let 和 const 两个关键字 ,用于声明变量,这两个命令和 var 有很多不同之处,两者之间也有一些细微的差别。

let 和 const 的用法类似于 var,但是 let 只在所在的代码块内有效,所以我们一般使用 let 替代 var, 用 const 来声明常量。

声明方式 变量提升 暂时性死区 重复声明 初始值 作用域
var 允许 不存在 允许 不需要 除块级
let 不允许 存在 不允许 不需要 块级
const 不允许 存在 不允许 需要 块级

今天我们主要学习下块级作用域。

块级作用域

(1) ES5没有块级作用域

​ 在ES6之前,没有块级作用域的概念,只有两种作用域,函数作用域和全局作用域。 所有的变量和函数声明都存在于这两种作用域中。

(2) 什么是块级作用域?

我找了个定义如下:

任何一对花括号中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。

举个例子

1
2
3
4
5
6
7
8
9
10
11
12
// 例子1
for(var i = 0; i < 10; i++) {
console.log(i); // 最后一次循环i=9,循环结束i++后,i=10
}
console.log(i);// 跳出 for 循环了,这里仍可以使用i变量

// 例子2
for (var i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i)
}, 1000);
}

执行例子1时,外层 console.log 会输出10,这是因为使用var声明的变量不具备块级作用域的特性。变量 i 只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。

执行例子2时,console.log 会输出10个10,这是因为 循环本身及十次 timeout 回调均共享唯一的变量 i 。当循环结束执行时,i 的值为10。

所以当第一个 timeout 执行时,调用的 i 为10。

注意:如果初始化变量时,没有使用 var声明,该变量会自动被添加到全局环境。

(3) ES5怎么创建块级作用域?
立即执行函数

“立即调用的函数表达式”(Immediately-Invoked Function Expression),简称 IIFE。

想进一步了解立即执行函数,可参考学习 IIFE学习

1
2
3
(function() {
// 这里是块级作用域
})();

function(){…}是一个匿名函数,包围它的一对括号将其转换为一个表达式,紧跟其后的一对括号调用了这个函数。

立即执行函数也可以理解为立即调用一个匿名函数,可以用来模拟块级作用域。

(4) ES6中的块级作用域

在ES6中,我们用 let 和 const 关键字来实现块级作用域。(跨级作用域的特性,let,const是类似的,因此主要讲let)

  • let声明的变量,只在所在的代码块{}内有效,在{}外不能访问(外层代码块不受内层代码块的影响)
1
2
3
4
{
let x = 1;
}
// 此处不能使用x变量,否则报错 Uncaught ReferenceError: x is not defined
  • for 循环中使用let,每一次循环的i其实都是一个新的变量

  • 块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了

参考文章:https://juejin.im/post/59e6a86d518825422c0cbb6f

# JS
JS中JSON 类型 —— 数据的迭代
浅谈 var、let 和 const (二)
  • 文章目录
  • 站点概览

WYP

知识管理,自我管理
12 日志
8 标签
GitHub E-Mail 简书
  1. 1. 浅谈 var、let 和 const (一)
    1. 1.1. 前言
    2. 1.2. 块级作用域
      1. 1.2.1. (1) ES5没有块级作用域
      2. 1.2.2. (2) 什么是块级作用域?
      3. 1.2.3. (3) ES5怎么创建块级作用域?
        1. 1.2.3.1. 立即执行函数
      4. 1.2.4. (4) ES6中的块级作用域
© 2019 – 2021 wyp